package org.covalence.core.util;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

import org.covalence.core.Observable;

/**
 * Extension to java.beans.PropertyChangeSupport to add convenience methods for
 * long, double and float data types.
 * 
 * @author tslusser
 *
 */
public class CPropertyChangeSupport extends PropertyChangeSupport {

	/**
	 * 
	 */
	private static final long serialVersionUID = -483559182056191081L;

	public CPropertyChangeSupport(Object sourceBean) {
		super(sourceBean);
	}

	/**
	 * Report a boolean bound property update to any registered listeners. No
	 * event is fired if old and new are equal and non-null.
	 * <p>
	 * This is merely a convenience wrapper around the more general
	 * firePropertyChange method that takes Object values.
	 * 
	 * @param propertyName
	 *            The programmatic name of the property that was changed.
	 * @param oldValue
	 *            The old value of the property.
	 * @param newValue
	 *            The new value of the property.
	 */
	public void firePropertyChange(String propertyName, boolean oldValue,
			boolean newValue) {
		if (oldValue == newValue) {
			return;
		}
		firePropertyChange(propertyName, Boolean.valueOf(oldValue), 
				Boolean.valueOf(newValue));
	}
	
	/**
	 * Report a long bound property update to any registered listeners. No
	 * event is fired if old and new are equal and non-null.
	 * <p>
	 * This is merely a convenience wrapper around the more general
	 * firePropertyChange method that takes Object values.
	 * 
	 * @param propertyName
	 *            The programmatic name of the property that was changed.
	 * @param oldValue
	 *            The old value of the property.
	 * @param newValue
	 *            The new value of the property.
	 */
	public void firePropertyChange(String propertyName, long oldValue,
			long newValue) {
		if (oldValue == newValue) {
			return;
		}
		firePropertyChange(propertyName, Long.valueOf(oldValue),
				Long.valueOf(newValue));
	}
	
	/**
	 * Report a double bound property update to any registered listeners. No
	 * event is fired if old and new are equal and non-null.
	 * <p>
	 * This is merely a convenience wrapper around the more general
	 * firePropertyChange method that takes Object values.
	 * 
	 * @param propertyName
	 *            The programmatic name of the property that was changed.
	 * @param oldValue
	 *            The old value of the property.
	 * @param newValue
	 *            The new value of the property.
	 */
	public void firePropertyChange(String propertyName, double oldValue,
			double newValue) {
		if (oldValue == newValue) {
			return;
		}
		firePropertyChange(propertyName, Double.valueOf(oldValue),
				Double.valueOf(newValue));
	}
	
	/**
	 * Report a float bound property update to any registered listeners. No
	 * event is fired if old and new are equal and non-null.
	 * <p>
	 * This is merely a convenience wrapper around the more general
	 * firePropertyChange method that takes Object values.
	 * 
	 * @param propertyName
	 *            The programmatic name of the property that was changed.
	 * @param oldValue
	 *            The old value of the property.
	 * @param newValue
	 *            The new value of the property.
	 */
	public void firePropertyChange(String propertyName, float oldValue,
			float newValue) {
		if (oldValue == newValue) {
			return;
		}
		firePropertyChange(propertyName, Float.valueOf(oldValue),
				Float.valueOf(newValue));
	}
	
	/**
	 * Move the listeners from one observable to another 
	 * @param source
	 * @param target
	 */
	public void moveListeners(Observable source, Observable target) {
		if (source == null)
			return;
		
		if (target == null)
			return;
		
		PropertyChangeListener[] pcls = source.getPropertyChangeListeners();
		for (PropertyChangeListener each : pcls) {
			source.removePropertyChangeListener(each);
			target.addPropertyChangeListener(each);
		}
	}
}
